package setting

import (
	"certificate-manager/pkg/constant"
	"certificate-manager/pkg/log"
	"go.uber.org/zap"
	"gopkg.in/ini.v1"
	"os"
	"strconv"
	"time"
)

type App struct {
	LetsEncryptUrl string
}

var AppSetting = &App{}

type Server struct {
	RunMode      string
	HttpPort     int
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
}

var ServerSetting = &Server{}

type feishuConfig struct {
	AppId, AppSecret, ChatId string
}

var FeishuSetting = &feishuConfig{}

type aliyunDNSConfig struct {
	RegionId, AccessKeyId, AccessKeySecret string
}

var AliyunDnsSetting = &aliyunDNSConfig{}

type RedisConfig struct {
	Addr, Port, Username, Password string
	Db                             int
}

var RedisSetting = &RedisConfig{}

var config *ini.File

func Setup() {
	var err error
	config, err = ini.Load("conf/app.ini")
	if err != nil {
		log.Logger.Error("settings init error. fail to parse 'conf/app.ini'.", zap.Any("err", err))
	}

	mapTo("server", ServerSetting)
	mapTo("feishu", FeishuSetting)
	mapTo("dns", AliyunDnsSetting)

	//init redis config
	//mapTo("redis", RedisSetting)
	InitRedisConfig()

	//init lets encrypt url
	//mapTo("app", AppSetting)
	InitLetsEncryptServerUrlConfig()

	ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second
	ServerSetting.WriteTimeout = ServerSetting.WriteTimeout * time.Second
}

// mapTo map section
func mapTo(section string, v interface{}) {
	err := config.Section(section).MapTo(v)
	if err != nil {
		log.Logger.Error("Config.Map error.", zap.Any("section", section), zap.Any("err", err))
	}
}

// InitRedisConfig init redis connect info
func InitRedisConfig() {
	// 获取 addr
	addr, ok := os.LookupEnv(constant.RedisHostName)
	if !ok {
		log.Logger.Error("REDIS_HOST not exist")
	}
	if addr == "" {
		log.Logger.Error("REDIS_HOST value is nil")
	}

	// 获取 port
	port, ok := os.LookupEnv(constant.RedisPortName)
	if !ok {
		log.Logger.Error("REDIS_PORT not exist")
	}
	if port == "" {
		log.Logger.Error("REDIS_PORT value is nil")
	}

	// 获取 user
	user, ok := os.LookupEnv(constant.RedisUserName)
	if !ok {
		log.Logger.Error("REDIS_USER not exist")
	}
	if user == "" {
		log.Logger.Error("REDIS_USER value is nil")
	}

	// 获取 pass
	pass, ok := os.LookupEnv(constant.RedisPassName)
	if !ok {
		log.Logger.Error("REDIS_PASS not exist")
	}
	if pass == "" {
		log.Logger.Error("REDIS_PASS value is nil")
	}

	// 获取 db
	db, ok := os.LookupEnv(constant.RedisDbName)
	if !ok {
		log.Logger.Error("REDIS_DB not exist")
	}
	if db == "" {
		log.Logger.Error("REDIS_DB value is nil")
	}
	dbi, err := strconv.Atoi(db)
	if err != nil {
		log.Logger.Sugar().Error(err)
	}

	RedisSetting.Addr = addr
	RedisSetting.Port = port
	RedisSetting.Username = user
	RedisSetting.Password = pass
	RedisSetting.Db = dbi
}

// InitLetsEncryptServerUrlConfig init lets encrypt server url
func InitLetsEncryptServerUrlConfig() {
	// 获取 url
	url, ok := os.LookupEnv(constant.LetsEncryptUrlName)
	if !ok {
		log.Logger.Error("LETSENCRYPT_URL not exist")
	}
	if url == "" {
		log.Logger.Error("LETSENCRYPT_URL value is nil")
	}

	AppSetting.LetsEncryptUrl = url
}
